<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
  <meta name="theme-color" content="#222">
  <meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

  <link rel="stylesheet" href="/css/main.css">



  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.2/css/all.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css">

  <script class="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {
      "hostname": "holidaypenguin.gitee.io",
      "root": "/",
      "images": "/images",
      "scheme": "Mist",
      "version": "8.2.2",
      "exturl": false,
      "sidebar": {
        "position": "right",
        "display": "always",
        "padding": 18,
        "offset": 12
      },
      "copycode": true,
      "bookmark": {
        "enable": false,
        "color": "#222",
        "save": "auto"
      },
      "fancybox": false,
      "mediumzoom": false,
      "lazyload": false,
      "pangu": false,
      "comments": {
        "style": "tabs",
        "active": null,
        "storage": true,
        "lazyload": false,
        "nav": null
      },
      "motion": {
        "enable": true,
        "async": true,
        "transition": {
          "post_block": "fadeIn",
          "post_header": "fadeInDown",
          "post_body": "fadeInDown",
          "coll_header": "fadeInLeft",
          "sidebar": "slideUpIn"
        }
      },
      "prism": false,
      "i18n": {
        "placeholder": "搜索...",
        "empty": "没有找到任何搜索结果：${query}",
        "hits_time": "找到 ${hits} 个搜索结果（用时 ${time} 毫秒）",
        "hits": "找到 ${hits} 个搜索结果"
      },
      "path": "/search.xml",
      "localsearch": {
        "enable": true,
        "trigger": "auto",
        "top_n_per_article": 1,
        "unescape": false,
        "preload": false
      }
    };
  </script>
  <meta property="og:type" content="article">
  <meta property="og:title" content="浏览器的同源策略">
  <meta property="og:url" content="https://holidaypenguin.gitee.io/blob/2019-04-02-browser-homology-policy/index.html">
  <meta property="og:site_name" content="HolidayPenguin">
  <meta property="og:locale" content="zh_CN">
  <meta property="og:image" content="https://holidaypenguin.gitee.io/images/js/0003.png">
  <meta property="article:published_time" content="2019-04-02T10:47:18.000Z">
  <meta property="article:modified_time" content="2019-04-02T10:47:18.000Z">
  <meta property="article:author" content="holidaypenguin">
  <meta property="article:tag" content="跨域">
  <meta property="article:tag" content="同源">
  <meta property="article:tag" content="CORS">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:image" content="https://holidaypenguin.gitee.io/images/js/0003.png">


  <link rel="canonical" href="https://holidaypenguin.gitee.io/blob/2019-04-02-browser-homology-policy/">


  <script class="page-configurations">
    // https://hexo.io/docs/variables.html
    CONFIG.page = {
      sidebar: "",
      isHome: false,
      isPost: true,
      lang: 'zh-CN'
    };
  </script>
  <title>浏览器的同源策略 | HolidayPenguin</title>





  <noscript>
    <style>
      body {
        margin-top: 2rem;
      }

      .use-motion .menu-item,
      .use-motion .sidebar,
      .use-motion .post-block,
      .use-motion .pagination,
      .use-motion .comments,
      .use-motion .post-header,
      .use-motion .post-body,
      .use-motion .collection-header {
        visibility: visible;
      }

      .use-motion .header,
      .use-motion .site-brand-container .toggle,
      .use-motion .footer {
        opacity: initial;
      }

      .use-motion .site-title,
      .use-motion .site-subtitle,
      .use-motion .custom-logo-image {
        opacity: initial;
        top: initial;
      }

      .use-motion .logo-line {
        transform: scaleX(1);
      }

      .search-pop-overlay,
      .sidebar-nav {
        display: none;
      }

      .sidebar-panel {
        display: block;
      }
    </style>
  </noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner">
        <div class="site-brand-container">
          <div class="site-nav-toggle">
            <div class="toggle" aria-label="切换导航栏" role="button">
              <span class="toggle-line"></span>
              <span class="toggle-line"></span>
              <span class="toggle-line"></span>
            </div>
          </div>

          <div class="site-meta">

            <a href="/" class="brand" rel="start">
              <i class="logo-line"></i>
              <h1 class="site-title">HolidayPenguin</h1>
              <i class="logo-line"></i>
            </a>
          </div>

          <div class="site-nav-right">
            <div class="toggle popup-trigger">
              <i class="fa fa-search fa-fw fa-lg"></i>
            </div>
          </div>
        </div>



        <nav class="site-nav">
          <ul class="main-menu menu">
            <li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li>
            <li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li>
            <li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
            <li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
            <li class="menu-item menu-item-search">
              <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
              </a>
            </li>
          </ul>
        </nav>



        <div class="search-pop-overlay">
          <div class="popup search-popup">
            <div class="search-header">
              <span class="search-icon">
                <i class="fa fa-search"></i>
              </span>
              <div class="search-input-container">
                <input autocomplete="off" autocapitalize="off" maxlength="80" placeholder="搜索..." spellcheck="false" type="search" class="search-input">
              </div>
              <span class="popup-btn-close" role="button">
                <i class="fa fa-times-circle"></i>
              </span>
            </div>
            <div class="search-result-container no-result">
              <div class="search-result-icon">
                <i class="fa fa-spinner fa-pulse fa-5x"></i>
              </div>
            </div>

          </div>
        </div>

      </div>


      <div class="toggle sidebar-toggle" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
      </div>

      <aside class="sidebar">

        <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
          <ul class="sidebar-nav">
            <li class="sidebar-nav-toc">
              文章目录
            </li>
            <li class="sidebar-nav-overview">
              站点概览
            </li>
          </ul>

          <div class="sidebar-panel-container">
            <!--noindex-->
            <div class="post-toc-wrap sidebar-panel">
              <div class="post-toc animated">
                <ol class="nav">
                  <li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5"><span class="nav-number">1.</span> <span class="nav-text">什么是同源策略</span></a></li>
                  <li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%B2%A1%E6%9C%89%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E7%9A%84%E4%B8%89%E4%B8%AA%E5%8D%B1%E9%99%A9%E5%9C%BA%E6%99%AF"><span class="nav-number">2.</span> <span class="nav-text">没有同源策略的三个危险场景</span></a>
                    <ol class="nav-child">
                      <li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B2%A1%E6%9C%89%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E9%99%90%E5%88%B6%E7%9A%84%E6%8E%A5%E5%8F%A3%E8%AF%B7%E6%B1%82"><span class="nav-number">2.1.</span> <span class="nav-text">没有同源策略限制的接口请求</span></a></li>
                      <li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B2%A1%E6%9C%89%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E9%99%90%E5%88%B6%E7%9A%84Dom%E6%9F%A5%E8%AF%A2"><span class="nav-number">2.2.</span> <span class="nav-text">没有同源策略限制的Dom查询</span></a></li>
                      <li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B2%A1%E6%9C%89%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E7%9A%84%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8"><span class="nav-number">2.3.</span> <span class="nav-text">没有同源策略的数据存储</span></a></li>
                    </ol>
                  </li>
                  <li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9C%89%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E7%9A%84%E6%83%85%E5%86%B5"><span class="nav-number">3.</span> <span class="nav-text">有同源策略的情况</span></a></li>
                  <li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%90%8C%E6%BA%90%E7%9A%84%E5%AE%9A%E4%B9%89"><span class="nav-number">4.</span> <span class="nav-text">同源的定义</span></a></li>
                  <li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%BA%90%E7%9A%84%E6%9B%B4%E6%94%B9"><span class="nav-number">5.</span> <span class="nav-text">源的更改</span></a></li>
                  <li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%B7%A8%E6%BA%90%E8%AE%BF%E9%97%AE"><span class="nav-number">6.</span> <span class="nav-text">跨源访问</span></a>
                    <ol class="nav-child">
                      <li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%B7%A8%E6%BA%90%E7%BD%91%E7%BB%9C%E8%AE%BF%E9%97%AE"><span class="nav-number">6.1.</span> <span class="nav-text">跨源网络访问</span></a></li>
                      <li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%B7%A8%E6%BA%90%E8%84%9A%E6%9C%ACAPI%E8%AE%BF%E9%97%AE"><span class="nav-number">6.2.</span> <span class="nav-text">跨源脚本API访问</span></a></li>
                      <li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%B7%A8%E6%BA%90%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E8%AE%BF%E9%97%AE"><span class="nav-number">6.3.</span> <span class="nav-text">跨源数据存储访问</span></a></li>
                    </ol>
                  </li>
                </ol>
                </li>
                <li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%80%BB%E7%BB%93"><span class="nav-number"></span> <span class="nav-text">总结</span></a></li>
                <li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%8F%82%E8%80%83"><span class="nav-number"></span> <span class="nav-text">参考</span></a>
              </div>
            </div>
            <!--/noindex-->

            <div class="site-overview-wrap sidebar-panel">
              <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
                <p class="site-author-name" itemprop="name">holidaypenguin</p>
                <div class="site-description" itemprop="description"></div>
              </div>
              <div class="site-state-wrap site-overview-item animated">
                <nav class="site-state">
                  <div class="site-state-item site-state-posts">
                    <a href="/archives/">

                      <span class="site-state-item-count">138</span>
                      <span class="site-state-item-name">日志</span>
                    </a>
                  </div>
                  <div class="site-state-item site-state-categories">
                    <a href="/categories/">

                      <span class="site-state-item-count">26</span>
                      <span class="site-state-item-name">分类</span></a>
                  </div>
                  <div class="site-state-item site-state-tags">
                    <a href="/tags/">

                      <span class="site-state-item-count">234</span>
                      <span class="site-state-item-name">标签</span></a>
                  </div>
                </nav>
              </div>
              <div class="links-of-author site-overview-item animated">
                <span class="links-of-author-item">
                  <a href="https://github.com/holidaypenguin" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;holidaypenguin" rel="noopener" target="_blank"><i class="github fa-fw"></i>GitHub</a>
                </span>
                <span class="links-of-author-item">
                  <a href="mailto:songshipeng2016@gmail.com" title="E-Mail → mailto:songshipeng2016@gmail.com" rel="noopener" target="_blank"><i class="envelope fa-fw"></i>E-Mail</a>
                </span>
              </div>



            </div>
          </div>
        </div>
      </aside>
      <div class="sidebar-dimmer"></div>


    </header>


    <div class="back-to-top" role="button">
      <i class="fa fa-arrow-up"></i>
      <span>0%</span>
    </div>

    <noscript>
      <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
    </noscript>


    <div class="main-inner post posts-expand">





      <div class="post-block">



        <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
          <link itemprop="mainEntityOfPage" href="https://holidaypenguin.gitee.io/blob/2019-04-02-browser-homology-policy/">

          <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
            <meta itemprop="image" content="/images/avatar.gif">
            <meta itemprop="name" content="holidaypenguin">
            <meta itemprop="description" content="">
          </span>

          <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
            <meta itemprop="name" content="HolidayPenguin">
          </span>
          <header class="post-header">
            <h1 class="post-title" itemprop="name headline">
              浏览器的同源策略
            </h1>

            <div class="post-meta-container">
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>

                  <time title="创建时间：2019-04-02 18:47:18" itemprop="dateCreated datePublished" datetime="2019-04-02T18:47:18+08:00">2019-04-02</time>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-folder"></i>
                  </span>
                  <span class="post-meta-item-text">分类于</span>
                  <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                    <a href="/categories/HTTP/" itemprop="url" rel="index"><span itemprop="name">HTTP</span></a>
                  </span>
                </span>


                <span id="/blob/2019-04-02-browser-homology-policy/" class="post-meta-item leancloud_visitors" data-flag-title="浏览器的同源策略" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
              </div>

              <div class="post-description">
                <!-- more -->
              </div>
            </div>
          </header>




          <div class="post-body" itemprop="articleBody">
            <h2 id="什么是同源策略"><a href="#什么是同源策略" class="headerlink" title="什么是同源策略"></a>什么是同源策略</h2>
            <p>首先来看一个比较官方的定义（<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy">浏览器的同源策略
              </a>）：同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。</p>
            <p>这是一个安全机制，假设我们没有这个安全机制会发生什么？</p>
            <h2 id="没有同源策略的三个危险场景"><a href="#没有同源策略的三个危险场景" class="headerlink" title="没有同源策略的三个危险场景"></a>没有同源策略的三个危险场景</h2>
            <p>这里只展示三个知道的场景，应该没有其它场景除非浏览器有所改变，如有其它场景可在文末补充。</p>
            <h3 id="没有同源策略限制的接口请求"><a href="#没有同源策略限制的接口请求" class="headerlink" title="没有同源策略限制的接口请求"></a>没有同源策略限制的接口请求</h3>
            <p>设想这样一种情况：A网站是一家银行，用户登录以后，又去浏览其他网站。如果其他网站可以读取A网站的 Cookie，会发生什么？</p>
            <p>很显然，如果 Cookie 包含隐私（比如存款总额），这些信息就会泄漏。更可怕的是，Cookie 往往用来保存用户的登录状态，如果用户没有退出登录，其他网站就可以冒充用户，为所欲为。因为浏览器同时还规定，提交表单不受同源政策的限制。</p>
            <p>由此可见，”同源政策”是必需的，否则 Cookie 可以共享，互联网就毫无安全可言了</p>
            <p>有一个小小的东西叫cookie大家应该知道，一般用来处理登录等场景，目的是让服务端知道谁发出的这次请求。如果你请求了接口进行登录，服务端验证通过后会在响应头加入Set-Cookie字段，然后下次再发请求的时候，浏览器会自动将cookie附加在HTTP请求的头字段Cookie中，服务端就能知道这个用户已经登录过了。知道这个之后，我们来看场景：</p>
            <ol>
              <li>你准备去清空你的购物车，于是打开了买买买网站 <a target="_blank" rel="noopener" href="http://www.maimaimai.com/">www.maimaimai.com</a> ，然后登录成功，一看，购物车东西这么少，不行，还得买多点。</li>
              <li>你在看有什么东西买的过程中，你的好基友发给你一个链接 <a target="_blank" rel="noopener" href="http://www.nidongde.com/">www.nidongde.com</a> ，一脸yin笑地跟你说：“你懂的”，你毫不犹豫打开了。</li>
              <li>你饶有兴致地浏览着 <a target="_blank" rel="noopener" href="http://www.nidongde.com/">www.nidongde.com</a> ，谁知这个网站暗地里做了些不可描述的事情！由于没有同源策略的限制，它向 <a target="_blank" rel="noopener" href="http://www.maimaimai.com/">www.maimaimai.com</a> 发起了请求！聪明的你一定想到上面的话“服务端验证通过后会在响应头加入Set-Cookie字段，然后下次再发请求的时候，浏览器会自动将cookie附加在HTTP请求的头字段Cookie中”，这样一来，这个不法网站就相当于登录了你的账号，可以为所欲为了！如果这不是一个买买买账号，而是你的银行账号，那……<br>这就是传说中的CSRF攻击<a target="_blank" rel="noopener" href="http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html">浅谈CSRF攻击方式</a>。<br>看了这波CSRF攻击我在想，即使有了同源策略限制，但cookie是明文的，还不是一样能拿下来。于是我看了一些cookie相关的文章<a target="_blank" rel="noopener" href="https://segmentfault.com/a/1190000004556040#articleHeader6">聊一聊 cookie</a>、<a target="_blank" rel="noopener" href="https://harttle.land/2015/08/10/cookie-session.html">Cookie/Session的机制与安全</a>，知道了服务端可以设置httpOnly，使得前端无法操作cookie，如果没有这样的设置，像XSS攻击就可以去获取到cookie<a target="_blank" rel="noopener" href="https://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.html">Web安全测试之XSS</a>；设置secure，则保证在https的加密通信中传输以防截获。</li>
            </ol>
            <h3 id="没有同源策略限制的Dom查询"><a href="#没有同源策略限制的Dom查询" class="headerlink" title="没有同源策略限制的Dom查询"></a>没有同源策略限制的Dom查询</h3>
            <ol>
              <li>有一天你刚睡醒，收到一封邮件，说是你的银行账号有风险，赶紧点进 <a target="_blank" rel="noopener" href="http://www.yinghang.com/">www.yinghang.com</a> 改密码。你吓尿了，赶紧点进去，还是熟悉的银行登录界面，你果断输入你的账号密码，登录进去看看钱有没有少了。</li>
              <li>睡眼朦胧的你没看清楚，平时访问的银行网站是 <a target="_blank" rel="noopener" href="http://www.yinhang.com/">www.yinhang.com</a> ，而现在访问的是 <a target="_blank" rel="noopener" href="http://www.yinghang.com/">www.yinghang.com</a> ，这个钓鱼网站做了什么呢？</li>
            </ol>
            <figure class="highlight html">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="tag">&lt;<span class="name">iframe</span> <span class="attr">name</span>=<span class="string">&quot;yinhang&quot;</span> <span class="attr">src</span>=<span class="string">&quot;www.yinhang.com&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">iframe</span>&gt;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <figure class="highlight js">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="comment">// 由于没有同源策略的限制，钓鱼网站可以直接拿到别的网站的Dom</span></span><br><span class="line"><span class="keyword">const</span> iframe = <span class="built_in">window</span>.frames[<span class="string">&#x27;yinhang&#x27;</span>]</span><br><span class="line"><span class="keyword">const</span> node = iframe.document.getElementById(<span class="string">&#x27;你输入账号密码的Input&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">`拿到了这个<span class="subst">$&#123;node&#125;</span>，我还拿不到你刚刚输入的账号密码吗`</span>)</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>由此我们知道，同源策略确实能规避一些危险，不是说有了同源策略就安全，只是说同源策略是一种浏览器最基本的安全机制，毕竟能提高一点攻击的成本。其实没有刺不穿的盾，只是攻击的成本和攻击成功后获得的利益成不成正比。</p>
            <h3 id="没有同源策略的数据存储"><a href="#没有同源策略的数据存储" class="headerlink" title="没有同源策略的数据存储"></a>没有同源策略的数据存储</h3>
            <p>数据存储中的数据虽然没有cookie那么重要，但是也是用户的个人，里面会记录用户的个人行为；假如个人行为泄露会影响用户的生活，有骚扰短信、营销电话、推荐邮件等方式</p>
            <h2 id="有同源策略的情况"><a href="#有同源策略的情况" class="headerlink" title="有同源策略的情况"></a>有同源策略的情况</h2>
            <p>有了同源策略上面的三个问题就可以避免掉（有些情况还是不能避免的），而且遵守同源策略的规则是可以适当做到跨域的。</p>
            <h2 id="同源的定义"><a href="#同源的定义" class="headerlink" title="同源的定义"></a>同源的定义</h2>
            <p>1995年，同源策略由 Netscape 公司引入浏览器。目前，所有浏览器都实行这个策略。</p>
            <p>如果两个页面的协议，端口（如果有指定）和主机都相同，则两个页面具有相同的源</p>
            <p>下表给出了相对<code>http://store.company.com/dir/page.html</code>同源检测的示例:</p>
            <table>
              <thead>
                <tr>
                  <th>URL</th>
                  <th>结果</th>
                  <th>原因</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td><code>http://store.company.com/dir2/other.html</code></td>
                  <td>成功</td>
                  <td>只有路径不同</td>
                </tr>
                <tr>
                  <td><code>http://store.company.com/dir/inner/another.html</code></td>
                  <td>成功</td>
                  <td>只有路径不同</td>
                </tr>
                <tr>
                  <td><code>https://store.company.com/secure.html</code></td>
                  <td>失败</td>
                  <td>不同协议 ( https和http )</td>
                </tr>
                <tr>
                  <td><code>http://store.company.com:81/dir/etc.html</code></td>
                  <td>失败</td>
                  <td>不同端口 ( http:// 80是默认的)</td>
                </tr>
                <tr>
                  <td><code>http://news.company.com/dir/other.html</code></td>
                  <td>失败</td>
                  <td>不同域名 ( news和store )</td>
                </tr>
              </tbody>
            </table>
            <p>另请参见<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Archive/Misc_top_level/Same-origin_policy_for_file:_URIs">文件的源定义: URLs</a></p>
            <h2 id="源的更改"><a href="#源的更改" class="headerlink" title="源的更改"></a>源的更改</h2>
            <p>比较官方的说法：脚本可以将 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Document/domain">document.domain</a> 的值设置为其当前域或其当前域的父域。如果将其设置为其当前域的父域，则这个较短的父域将用于后续源检查。</p>
            <p>假设 <code>http://store.company.com/dir/other.html</code> 文档中的一个脚本执行以下语句：</p>
            <figure class="highlight js">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="built_in">document</span>.domain = <span class="string">&quot;company.com&quot;</span>;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>这条语句执行之后，页面将会成功地通过对 <code>http://company.com/dir/page.html</code> 的同源检测（假设<code>http://company.com/dir/page.html</code> 将其 <code>document.domain</code> 设置为“<code>company.com</code>”，以表明它希望允许这样做 ）。然而，<code>company.com</code> 不能设置 <code>document.domain</code> 为 <code>othercompany.com</code>，因为它不是 <code>company.com</code> 的父域。</p>
            <p>端口号是由浏览器另行检查的。任何对<code>document.domain</code>的赋值操作，包括 <code>document.domain = document.domain</code> 都会导致端口号被重写为 <code>null</code> 。因此 <code>company.com:8080</code> 不能仅通过设置 <code>document.domain = &quot;company.com&quot;</code> 来与<code>company.com</code> 通信。必须在他们双方中都进行赋值，以确保端口号都为 <code>null</code> 。</p>
            <blockquote>
              <p>使用 document.domain 来允许<strong>子域安全访问其父域</strong>时，您需要在父域和子域中设置 document.domain 为相同的值。不这样做可能会导致权限错误。</p>
            </blockquote>
            <h2 id="跨源访问"><a href="#跨源访问" class="headerlink" title="跨源访问"></a>跨源访问</h2>
            <p>根据上面说的三种异常情况主要分为以下三种跨源访问：</p>
            <ol>
              <li>跨源网络访问<br>同源策略控制了不同源之间的交互，例如在使用<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a>会受到同源策略的约束。</li>
              <li>跨源脚本API访问<br>Javascript的APIs中，如 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement">iframe.contentWindow</a>, <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/parent">window.parent</a>, <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open">window.open</a> 和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/opener">window.opener</a> 允许文档间直接相互引用。当两个文档的源不同时，这些引用方式将对 <a target="_blank" rel="noopener" href="https://html.spec.whatwg.org/multipage/browsers.html#security-window">Window</a> 和 <a target="_blank" rel="noopener" href="https://html.spec.whatwg.org/multipage/history.html#security-location">Location</a>对象的访问添加限制</li>
              <li>跨源数据存储访问<br>存储在浏览器中的数据，如<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/API/DOM/Storage">Storage</a>、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API">IndexedDB</a>、Cookie等。</li>
            </ol>
            <h3 id="跨源网络访问"><a href="#跨源网络访问" class="headerlink" title="跨源网络访问"></a>跨源网络访问</h3>
            <p>同源策略控制了不同源之间的交互。例如在使用<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a>会受到同源策略的约束，可使用一些方法允许跨域的方法。同时还有允许跨源的元素。而且跨源网络访问是跨源里面的常见问题。 这些交互通常分为三类：</p>
            <ul>
              <li>通常允许跨域写操作（Cross-origin writes）。例如链接（<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a">links</a>但在使用其中的属性download时需要同源），重定向以及表单提交。特定少数的HTTP请求需要添加 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTTP/Access_control_CORS#Preflighted_requests">preflight</a>。</li>
              <li>通常允许跨域资源嵌入（Cross-origin embedding）。之后下面会举例说明。</li>
              <li>通常不允许跨域读操作（Cross-origin reads）。但常可以通过内嵌资源来巧妙的进行读取访问。</li>
            </ul>
            <h4 id="允许跨域资源嵌入的元素与示例"><a href="#允许跨域资源嵌入的元素与示例" class="headerlink" title="允许跨域资源嵌入的元素与示例"></a>允许跨域资源嵌入的元素与示例</h4>
            <ul>
              <li><code>&lt;script src=&quot;...&quot;&gt;&lt;/script&gt;</code> 标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。</li>
              <li><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;...&quot;&gt;</code> 标签嵌入CSS。由于CSS的松散的语法规则，CSS的跨域需要一个设置正确的Content-Type 消息头。</li>
              <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img">&lt;img&gt;</a>嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,…</li>
              <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video">&lt;video&gt;</a> 和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/audio">&lt;audio&gt;</a>嵌入多媒体资源。</li>
              <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/object">&lt;object&gt;</a>, <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/embed">&lt;embed&gt;</a> 和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/applet">&lt;applet&gt;</a> 的插件。</li>
              <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/CSS/@font-face">@font-face</a> 引入的字体。一些浏览器允许跨域字体（ cross-origin fonts），一些需要同源字体（same-origin fonts）。</li>
              <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/frame">&lt;frame&gt;</a> 和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTML/Element/iframe">&lt;iframe&gt;</a> 载入的任何资源。站点可以使用<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTTP/X-Frame-Options">X-Frame-Options</a>消息头来阻止这种形式的跨域交互。</li>
            </ul>
            <h4 id="如何允许跨源访问"><a href="#如何允许跨源访问" class="headerlink" title="如何允许跨源访问"></a>如何允许跨源访问</h4>
            <p>当前网络环境下不允许跨源网络访问的只有<code>XMLHttpRequest</code>，因为 ajax 使用的就是 XMLHttpRequest，因此单独开辟一篇文章介绍<a href="../2019-01-14-ajax-cross-domain/">ajax 跨域</a></p>
            <h4 id="如何阻止跨源访问"><a href="#如何阻止跨源访问" class="headerlink" title="如何阻止跨源访问"></a>如何阻止跨源访问</h4>
            <ul>
              <li>阻止跨域写操作，只要检测请求中的一个不可测的标记(CSRF token)即可，这个标记被称为<a target="_blank" rel="noopener" href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29">Cross-Site Request Forgery (CSRF)</a> 标记。必须使用这个标记来阻止页面的跨站读操作。</li>
              <li>阻止资源的跨站读取，需要保证该资源是不可嵌入的。阻止嵌入行为是必须的，因为嵌入资源通常向其暴露信息。</li>
              <li>阻止跨站嵌入，需要确保你的资源不能是以上列出的可嵌入资源格式。多数情况下浏览器都不会遵守 Conten-Type 消息头。例如，如果您在HTML文档中指定 <code>&lt;script\&gt;</code> 标记，则浏览器将尝试将HTML解析为JavaScript。 当您的资源不是您网站的入口点时，您还可以使用CSRF令牌来防止嵌入</li>
            </ul>
            <ol>
              <li>
                <p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/HTTP/X-Frame-Options">X-Frame-Options</a>阻止<code>iframe</code>的嵌套<br>可以在nginx中设置<a target="_blank" rel="noopener" href="https://www.haoht123.com/680.html">nginx配置X-Frame-Options响应头</a></p>
              </li>
              <li>
                <p>这里引申出另外一个问题，防盗链。<br>参考<a href="../2019-04-08-anti-theft-chain/">防盗链</a></p>
              </li>
              <li>
                <p>CSRF<br>参考<a href="../2019-04-08-talking-about-csrf/">浅谈CSRF</a></p>
              </li>
            </ol>
            <h4 id="canvas操作图片的跨域问题"><a href="#canvas操作图片的跨域问题" class="headerlink" title="canvas操作图片的跨域问题"></a>canvas操作图片的跨域问题</h4>
            <p><a href="https://holidaypenguin.gitee.io//blob/2019-03-25-solve-the-cross-domain-problem-of-canvas-image-getimagedata-and-todataurl/">解决canvas图片getImageData,toDataURL跨域问题</a></p>
            <h3 id="跨源脚本API访问"><a href="#跨源脚本API访问" class="headerlink" title="跨源脚本API访问"></a>跨源脚本API访问</h3>
            <p>Javascript的APIs中，如 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement">iframe.contentWindow</a>, <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/parent">window.parent</a>, <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open">window.open</a> 和 <a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/opener">window.opener</a> 允许文档间直接相互引用。当两个文档的源不同时，这些引用方式将对 <a target="_blank" rel="noopener" href="https://html.spec.whatwg.org/multipage/browsers.html#security-window">Window</a> 和 <a target="_blank" rel="noopener" href="https://html.spec.whatwg.org/multipage/history.html#security-location">Location</a>对象的访问添加限制。</p>
            <p>** 允许以下对 Window 属性的跨源访问 **</p>
            <ul>
              <li>方法<ul>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/blur">window.blur</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/close">window.close</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/focus">window.focus</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage">window.postMessage</a></li>
                </ul>
              </li>
              <li>属性<ul>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/closed">window.closed</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/frames">window.frames</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/length">window.length</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/location">window.location</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/opener">window.opener</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/parent">window.parent</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/self">window.self</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/top">window.top</a></li>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/window">window.window</a> </li>
                </ul>
              </li>
            </ul>
            <p>** 允许以下对 Location 属性的跨源访问 **</p>
            <ul>
              <li>方法<ul>
                  <li><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Location/replace">location.replace</a></li>
                </ul>
              </li>
              <li>属性<ul>
                  <li><a href="URLUtils.href">URLUtils.href</a></li>
                </ul>
              </li>
            </ul>
            <p>如果两个网页不同源，就无法拿到对方的DOM。典型的例子是<code>iframe</code>窗口和<code>window.open</code>方法打开的窗口，它们与父窗口无法通信。 </p>
            <p>比如，父窗口运行下面的命令，如果<code>iframe</code>窗口不是同源，就会报错。</p>
            <figure class="highlight js">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="built_in">document</span>.getElementById(<span class="string">&quot;myIFrame&quot;</span>).contentWindow.document</span><br><span class="line"><span class="comment">// Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>上面命令中，父窗口想获取子窗口的DOM，因为跨源导致报错。反之亦然，子窗口获取主窗口的DOM也会报错。</p>
            <p>可通过以下几个方法完成跨源</p>
            <h4 id="使用-window-postMessage-跨源"><a href="#使用-window-postMessage-跨源" class="headerlink" title="使用 window.postMessage 跨源"></a>使用 window.postMessage 跨源</h4>
            <p>这个方法为什么放在这里，是因为该方法是最应该使用的方法，后面的方法都是小道而。</p>
            <p>window.postMessage() 是HTML5的一个接口，专注实现不同窗口不同页面的跨域通讯。</p>
            <p>这里是<a target="_blank" rel="noopener" href="http://localhost:9099/#/crossDomain%EF%BC%8C%E5%8F%91%E6%B6%88%E6%81%AF%E6%96%B9">http://localhost:9099/#/crossDomain，发消息方</a></p>
            <figure class="highlight xml">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;postMessage&quot;</span>&gt;</span>给http://crossDomain.com:9099发消息<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">iframe</span> <span class="attr">name</span>=<span class="string">&quot;crossDomainIframe&quot;</span> <span class="attr">src</span>=<span class="string">&quot;http://crossdomain.com:9099&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">iframe</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span><br><span class="line">  mounted () &#123;</span><br><span class="line"><span class="javascript">    <span class="built_in">window</span>.addEventListener(<span class="string">&#x27;message&#x27;</span>, <span class="function">(<span class="params">e</span>) =&gt;</span> &#123;</span></span><br><span class="line"><span class="javascript">      <span class="comment">// 这里一定要对来源做校验</span></span></span><br><span class="line"><span class="javascript">      <span class="keyword">if</span> (e.origin === <span class="string">&#x27;http://crossdomain.com:9099&#x27;</span>) &#123;</span></span><br><span class="line"><span class="javascript">        <span class="comment">// 来自http://crossdomain.com:9099的结果回复</span></span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(e.data)</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;,</span><br><span class="line">  methods: &#123;</span><br><span class="line"><span class="javascript">    <span class="comment">// 向http://crossdomain.com:9099发消息</span></span></span><br><span class="line">    postMessage () &#123;</span><br><span class="line"><span class="javascript">      <span class="keyword">const</span> iframe = <span class="built_in">window</span>.frames[<span class="string">&#x27;crossDomainIframe&#x27;</span>]</span></span><br><span class="line"><span class="javascript">      iframe.postMessage(<span class="string">&#x27;我是[http://localhost:9099], 麻烦你查一下你那边有没有id为app的Dom&#x27;</span>, <span class="string">&#x27;http://crossdomain.com:9099&#x27;</span>)</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>这里是<a href="http://crossdomain.com:9099，接收消息方">http://crossdomain.com:9099，接收消息方</a></p>
            <figure class="highlight xml">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    我是http://crossdomain.com:9099</span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span><br><span class="line">  mounted () &#123;</span><br><span class="line"><span class="javascript">    <span class="built_in">window</span>.addEventListener(<span class="string">&#x27;message&#x27;</span>, <span class="function">(<span class="params">e</span>) =&gt;</span> &#123;</span></span><br><span class="line"><span class="javascript">      <span class="comment">// 这里一定要对来源做校验</span></span></span><br><span class="line"><span class="javascript">      <span class="keyword">if</span> (e.origin === <span class="string">&#x27;http://localhost:9099&#x27;</span>) &#123;</span></span><br><span class="line"><span class="javascript">        <span class="comment">// http://localhost:9099发来的信息</span></span></span><br><span class="line"><span class="javascript">        <span class="built_in">console</span>.log(e.data)</span></span><br><span class="line"><span class="javascript">        <span class="comment">// e.source可以是回信的对象，其实就是http://localhost:9099窗口对象(window)的引用</span></span></span><br><span class="line"><span class="javascript">        <span class="comment">// e.origin可以作为targetOrigin</span></span></span><br><span class="line"><span class="javascript">        e.source.postMessage(<span class="string">`我是[http://crossdomain.com:9099]，我知道了兄弟，这就是你想知道的结果：<span class="subst">$&#123;<span class="built_in">document</span>.getElementById(<span class="string">&#x27;app&#x27;</span>) ? <span class="string">&#x27;有id为app的Dom&#x27;</span> : <span class="string">&#x27;没有id为app的Dom&#x27;</span>&#125;</span>`</span>, e.origin);</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>结果可以看到</p>
            <p><img src="" data-original="/images/js/0003.png" alt="0003"></p>
            <h4 id="使用-document-domain-跨源"><a href="#使用-document-domain-跨源" class="headerlink" title="使用 document.domain 跨源"></a>使用 document.domain 跨源</h4>
            <p>该方法的使用过程在<code>源的更改</code>一节已经讲过，这个方法是有限制的，只能是子域名设置为父域名</p>
            <h4 id="使用-URL-锚点标记"><a href="#使用-URL-锚点标记" class="headerlink" title="使用 URL 锚点标记"></a>使用 URL 锚点标记</h4>
            <p>URL锚点标记是URL的<code>#</code>号及其后面的部分，<code>#</code>之后的部分（也称为片段标识符）</p>
            <p>父窗口可以把信息，写入子窗口的片段标识符。</p>
            <figure class="highlight js">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="keyword">var</span> src = originURL + <span class="string">&#x27;#&#x27;</span> + data;</span><br><span class="line"><span class="built_in">document</span>.getElementById(<span class="string">&#x27;myIFrame&#x27;</span>).src = src;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>子窗口通过监听<code>hashchange</code>事件得到通知。</p>
            <figure class="highlight js">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line"><span class="built_in">window</span>.onhashchange = <span class="function"><span class="keyword">function</span> <span class="title">checkMessage</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> message = <span class="built_in">window</span>.location.hash;</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>

            <p>同样的，子窗口也可以改变父窗口的片段标识符。</p>
            <figure class="highlight js">
              <table>
                <tr>
                  <td class="gutter">
                    <pre><span class="line">1</span><br></pre>
                  </td>
                  <td class="code">
                    <pre><span class="line">parent.location.href= target + <span class="string">&quot;#&quot;</span> + hash;</span><br></pre>
                  </td>
                </tr>
              </table>
            </figure>
            <p>父窗口也同样通过监听<code>hashchange</code>事件得到通知。</p>
            <h4 id="使用-window-name-属性"><a href="#使用-window-name-属性" class="headerlink" title="使用 window.name 属性"></a>使用 window.name 属性</h4>
            <p>浏览器窗口有<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/name">window.name</a>属性。这个属性的最大特点是，无论是否同源，只要在同一个窗口里，前一个网页设置了这个属性，后一个网页可以读取它。</p>
            <h3 id="跨源数据存储访问"><a href="#跨源数据存储访问" class="headerlink" title="跨源数据存储访问"></a>跨源数据存储访问</h3>
            <p>存储在浏览器中的数据，如<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/API/DOM/Storage">Storage</a>、<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API">IndexedDB</a>、以源进行分割。每个源都拥有自己单独的存储空间，一个源中的Javascript脚本不能对属于其它源的数据进行读写操作。</p>
            <ul>
              <li>这两个可以在<code>iframe</code>中根据情况使用<code>跨源API访问</code>的四种方法取Storage中的值，还是推荐使用postMessage方式。</li>
            </ul>
            <p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies">Cookies</a> 使用不同的源定义方式。一个页面可以为本域和任何父域设置cookie，只要是父域不是公共后缀（<a target="_blank" rel="noopener" href="https://publicsuffix.org/">public suffix</a>）即可（举例说明下：如果页面域名为 <a target="_blank" rel="noopener" href="http://www.baidu.com/">www.baidu.com</a>, domain可以设置为“<a target="_blank" rel="noopener" href="http://www.baidu.com”,也可以设置为“baidu.com”,但不能设置为“.com”或“com”).firefox/">www.baidu.com”，也可以设置为“baidu.com”，但不能设置为“.com”或“com”）。Firefox</a> 和 Chrome 使用 Public Suffix List 决定一个域是否是一个公共后缀（public suffix）。Internet Explorer使用其自己的内部方法来确定域是否是公共后缀。不管使用哪个协议（HTTP/HTTPS）或端口号，浏览器都允许给定的域以及其任何子域名(sub-domains) 访问 cookie。设置 cookie 时，你可以使用Domain，Path，Secure，和Http-Only标记来限定其访问性。</p>
            <ul>
              <li>cookie跨域的方式如果只是简单的跨域可以设置cookie的domain为一级域名，所有的子域名都可以使用。</li>
              <li>如果是复杂的跨域，只能是在<code>iframe</code>中根据情况使用<code>跨源API访问</code>的postMessage和锚点标记。</li>
              <li>不使用document.domain是因为可以通过一级域名的方式，如果感觉使用这种方式比较开心，也可以使用。</li>
            </ul>
            <h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1>
            <ul>
              <li>允许跨源访问的元素：script、link、img、video、audio、object、embed、applet、@font-face、frame、iframe。</li>
              <li>ajax跨域的解决方法：可跨源的元素、JSONP、CORS、Nginx、WebSocket。</li>
              <li>如何跨源脚本API访问：postMessage、document.domain、片段标识符、window.name。</li>
              <li>如何跨源数据存储访问：postMessage、document.domain、片段标识符、window.name、设置父域cookie（cookie专用）</li>
            </ul>
            <h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1>
            <p><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy">浏览器的同源策略
              </a><br><a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Archive/Misc_top_level/Same-origin_policy_for_file:_URIs">档案同源策略
              </a><br><a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests">Cross-Origin Resource Sharing (CORS)
              </a><br><a target="_blank" rel="noopener" href="https://segmentfault.com/a/1190000015597029">不要再问我跨域的问题了</a><br><a target="_blank" rel="noopener" href="http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html">浏览器同源政策及其规避方法</a><br><a target="_blank" rel="noopener" href="http://www.ruanyifeng.com/blog/2016/04/cors.html">跨域资源共享 CORS 详解</a><br><a target="_blank" rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web">Identifying resources on the Web
              </a> </p>

          </div>





          <footer class="post-footer">
            <div class="post-tags">
              <a href="/tags/%E8%B7%A8%E5%9F%9F/" rel="tag"># 跨域</a>
              <a href="/tags/%E5%90%8C%E6%BA%90/" rel="tag"># 同源</a>
              <a href="/tags/CORS/" rel="tag"># CORS</a>
            </div>



            <div class="post-nav">
              <div class="post-nav-item">
                <a href="/blob/2019-04-01-cookie-and-session/" rel="prev" title="cookie与session">
                  <i class="fa fa-chevron-left"></i> cookie与session
                </a>
              </div>
              <div class="post-nav-item">
                <a href="/blob/2019-04-08-anti-theft-chain/" rel="next" title="防盗链">
                  防盗链 <i class="fa fa-chevron-right"></i>
                </a>
              </div>
            </div>
          </footer>
        </article>
      </div>







      <script>
        window.addEventListener('tabs:register', () => {
          let {
            activeClass
          } = CONFIG.comments;
          if (CONFIG.comments.storage) {
            activeClass = localStorage.getItem('comments_active') || activeClass;
          }
          if (activeClass) {
            const activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
            if (activeTab) {
              activeTab.click();
            }
          }
        });
        if (CONFIG.comments.storage) {
          window.addEventListener('tabs:click', event => {
            if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
            const commentClass = event.target.classList[1];
            localStorage.setItem('comments_active', commentClass);
          });
        }
      </script>
    </div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


      <div class="copyright">
        &copy;
        <span itemprop="copyrightYear">2021</span>
        <span class="with-love">
          <i class="fa fa-heart"></i>
        </span>
        <span class="author" itemprop="copyrightHolder">holidaypenguin</span>
      </div>
      <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/mist/" class="theme-link" rel="noopener" target="_blank">NexT.Mist</a> 强力驱动
      </div>

    </div>
  </footer>


  <script size="300" alpha="0.1" zIndex="-1" src="https://cdn.jsdelivr.net/npm/ribbon.js@1.0.2/dist/ribbon.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js"></script>
  <script src="/js/love.js"></script>

  <script src="/js/development.js"></script>
  <script src="/js/utils.js"></script>
  <script src="/js/motion.js"></script>
  <script src="/js/schemes/muse.js"></script>
  <script src="/js/next-boot.js"></script>


  <script src="/js/local-search.js"></script>









  <script>
    (function() {
      function leancloudSelector(url) {
        url = encodeURI(url);
        return document.getElementById(url).querySelector('.leancloud-visitors-count');
      }

      function addCount(Counter) {
        const visitors = document.querySelector('.leancloud_visitors');
        const url = decodeURI(visitors.id);
        const title = visitors.dataset.flagTitle;

        Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({
            url
          })))
          .then(response => response.json())
          .then(({
            results
          }) => {
            if (results.length > 0) {
              const counter = results[0];
              leancloudSelector(url).innerText = counter.time + 1;
              Counter('put', '/classes/Counter/' + counter.objectId, {
                  time: {
                    '__op': 'Increment',
                    'amount': 1
                  }
                })
                .catch(error => {
                  console.error('Failed to save visitor count', error);
                });
            } else {
              Counter('post', '/classes/Counter', {
                  title,
                  url,
                  time: 1
                })
                .then(response => response.json())
                .then(() => {
                  leancloudSelector(url).innerText = 1;
                })
                .catch(error => {
                  console.error('Failed to create', error);
                });
            }
          })
          .catch(error => {
            console.error('LeanCloud Counter Error', error);
          });
      }

      function showTime(Counter) {
        const visitors = document.querySelectorAll('.leancloud_visitors');
        const entries = [...visitors].map(element => {
          return decodeURI(element.id);
        });

        Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({
            url: {
              '$in': entries
            }
          })))
          .then(response => response.json())
          .then(({
            results
          }) => {
            for (let url of entries) {
              const target = results.find(item => item.url === url);
              leancloudSelector(url).innerText = target ? target.time : 0;
            }
          })
          .catch(error => {
            console.error('LeanCloud Counter Error', error);
          });
      }

      const {
        app_id,
        app_key,
        server_url
      } = {
        "enable": true,
        "app_id": "povuqNsSqFodlakVIwtEX5kb-gzGzoHsz",
        "app_key": "zXD40RDtDB3DMtpC89k0AK7g",
        "server_url": null,
        "security": false
      };

      function fetchData(api_server) {
        const Counter = (method, url, data) => {
          return fetch(`${api_server}/1.1${url}`, {
            method,
            headers: {
              'X-LC-Id': app_id,
              'X-LC-Key': app_key,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(data)
          });
        };
        if (CONFIG.page.isPost) {
          if (CONFIG.hostname !== location.hostname) return;
          addCount(Counter);
        } else if (document.querySelectorAll('.post-title-link').length >= 1) {
          showTime(Counter);
        }
      }

      const api_server = app_id.slice(-9) === '-MdYXbMMI' ? `https://${app_id.slice(0, 8).toLowerCase()}.api.lncldglobal.com` : server_url;

      if (api_server) {
        fetchData(api_server);
      } else {
        fetch('https://app-router.leancloud.cn/2/route?appId=' + app_id)
          .then(response => response.json())
          .then(({
            api_server
          }) => {
            fetchData('https://' + api_server);
          });
      }
    })();
  </script>



<script>
            window.imageLazyLoadSetting = {
                isSPA: false,
                preloadRatio: 1,
                processImages: null,
            };
        </script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script><script>!function(n){n.imageLazyLoadSetting.processImages=o;var e=n.imageLazyLoadSetting.isSPA,i=n.imageLazyLoadSetting.preloadRatio||1,r=Array.prototype.slice.call(document.querySelectorAll("img[data-original]"));function o(){e&&(r=Array.prototype.slice.call(document.querySelectorAll("img[data-original]")));for(var t,a=0;a<r.length;a++)0<=(t=(t=r[a]).getBoundingClientRect()).bottom&&0<=t.left&&t.top<=(n.innerHeight*i||document.documentElement.clientHeight*i)&&function(){var t,e,n,i,o=r[a];t=o,e=function(){r=r.filter(function(t){return o!==t})},n=new Image,i=t.getAttribute("data-original"),n.onload=function(){t.src=i,e&&e()},t.src!==i&&(n.src=i)}()}o(),n.addEventListener("scroll",function(){var t,e;t=o,e=n,clearTimeout(t.tId),t.tId=setTimeout(function(){t.call(e)},500)})}(this);</script></body>

</html>